using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.ComponentModel;
using WozLib.UI.Ink.SketchObjects;

namespace WozLib.UI.Ink.SketchProperties
{
  public enum WozPropertyType
  {
    // USER
    BehindInk,        // indicates whether something should appear behind the ink
                      // doesn't apply to ink (obviously - although it is possible using paths)
                      // this is necessary to make something "selectable"

    FillColor,        // the fill color of a shape or stroke

    ForegroundColor,       // the fill of the foreground

    FillImageUrl,     // storing images in a way that they can be 
                      //used as a brush but also go across the network

    ForegroundImageUrl,

    GradientDirection, // a fill gradient expressesd in a way a gradient brush can be created

    GradientStartColor, // a fill gradient expressesd in a way a gradient brush can be created

    GradientEndColor, // a fill gradient expressesd in a way a gradient brush can be created

    Cursor,           // the cursor that you see when you mouse over this thing
                      // applies to non-ink

    EditMode,         // ink vs gesture vs none

    Selectable,       // implies moveable and resizeable

    Text,             // the text inside an object with text

    Editable,         // whether the control is currently editable, like the text in a label

    StrokeColor,      // color of the outline

    StrokeDashed,     // whether the outline is dashed

    StrokeThickness,  // the thickness of the outline

    InkThickness,

    Font,             // the name of the font family used for some text

    FontSize,         // the size of a font for some text

    CornerRoundness,  // the RadiusX and RadiusY of the round corners of a rectangle (in logical px)

    LinkedScreenID,   // the server object ID of the screen that the link should navigate to

    //NON-USER

    Bounds,           // a Rect of the bounding box

    LineGeometry,     // the geometry for a line

    RectGeometry,     // the geometry for rectangles and ellipses

    Opacity,          // the opacity of some elements

    Ink               // the binary ink data for a stroke
  }



  [XmlInclude(typeof(OpacitySketchProperty))]
  [XmlInclude(typeof(FontSizeSketchProperty))]
  [XmlInclude(typeof(CornerRoundednessSketchProperty))]
  [XmlInclude(typeof(RectGeometrySketchProperty))]
  [XmlInclude(typeof(BooleanSketchProperty))]
  [XmlInclude(typeof(LineGeometrySketchProperty))]
  [XmlInclude(typeof(InkThicknessSketchProperty))]
  [XmlInclude(typeof(BoundsSketchProperty))]
  [XmlInclude(typeof(ThicknessSketchProperty))]
  [XmlInclude(typeof(ColorSketchProperty))]
  [XmlInclude(typeof(StrokeSketchProperty))]
  [XmlInclude(typeof(StringSketchProperty))]
  [XmlInclude(typeof(LongSketchProperty))]
  public class SketchProperty : ICloneable, INotifyPropertyChanged
  {
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    protected void FirePropertyChanged(string propertyName)
    {
      if (this.PropertyChanged != null)
      {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
    }
    #endregion

    public delegate void WozPropertyChangedDelegate(SketchProperty wozProperty);

    public event WozPropertyChangedDelegate WozPropertyChanged;

    protected void NotifyPropertyChanged()
    {
      if (WozPropertyChanged != null)
      {
        WozPropertyChanged(this);
      }
    }
    
    [XmlAttribute("WozPropertyType")]
    public WozPropertyType WozPropertyType
    {
      get
      {
        return _WozPropertyType;
      }
      set
      {
        _WozPropertyType = value;
      }
    } private WozPropertyType _WozPropertyType;

    public SketchProperty()
    {
    }

    public SketchProperty(WozPropertyType wozPropertyType)
    {
      _WozPropertyType = wozPropertyType;
    }

    public virtual object Clone()
    {
      return new SketchProperty(WozPropertyType);
    }

    /// <summary>
    /// Should always be overridden.
    /// 
    /// This generic .equals just returns whether it is of the same WozPropertyType
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public override bool Equals(object obj)
    {
      if (obj is SketchProperty && (obj as SketchProperty).WozPropertyType == this.WozPropertyType)
      {
        return true;
      }
      else
      {
        return false;
      }
    }

    public string Description
    {
      get { return ToString(); }
    }

    public override string ToString()
    {
      switch (WozPropertyType)
      {
        case WozPropertyType.BehindInk:
          return "behind ink";
        case WozPropertyType.FillColor:
          return "fill color";
        case WozPropertyType.StrokeColor:
          return "stroke color";
        case WozPropertyType.Cursor:
          return "cursor";
        case WozPropertyType.EditMode:
          return "edit mode";
        case WozPropertyType.FillImageUrl:
          return "image";
        case WozPropertyType.Ink:
          return "ink";
        case WozPropertyType.Selectable:
          return "selectable";
        case WozPropertyType.Text:
          return "text";
        case WozPropertyType.Editable:
          return "editable";
        case WozPropertyType.StrokeThickness:
          return "stroke thickness";
        case WozPropertyType.InkThickness:
          return "thickness";
        case WozPropertyType.StrokeDashed:
          return "stroke dashed?";
        case WozPropertyType.CornerRoundness:
          return "corner roundedness";
        case WozPropertyType.ForegroundColor:
          return "foreground color";
        case WozPropertyType.FontSize:
          return "font size";
        case WozPropertyType.Font:
          return "font";
        case WozPropertyType.RectGeometry:
          return "rectangle geometry";
        case WozPropertyType.Opacity:
          return "opacity";
        case WozPropertyType.GradientEndColor:
          return "end color";
        case WozPropertyType.GradientStartColor:
          return "start color";
        default:
          return "WozProperty";
      }
    }

    public virtual CascadingProperty CreateCascadingProperty(List<ISketchObject> iWozObjects)
    {
      // just a generic one, derived classes should overrride
      return new CascadingProperty(iWozObjects, this);
    }
  }
}
